/*
 * RSATools.cpp
 *
 *   Created on: 2010-3-24     
 *  Description: 
 *    Copyright: 2010 @ ICT Li Heyuan
 */

#include "../include/RSATools.h"

#include <iostream>
#include <sstream>
using std::ostringstream;

#include "../include/encode.h"
#include "../include/decode.h"

RSATools::RSATools(unsigned int size)
{
	//初始化rsa参数
	_rsa_param.GenerateRandomWithKeySize(_rng, size);
}

RSATools::~RSATools()
{
}

RSATools& RSATools::operator =(const RSATools &right)
{
	//	this->_rng = right._rng;
	this->_rsa_param = right._rsa_param;
	return *this;
}

RSATools::RSATools(const RSATools & other)
{
	//	this->_rng = other._rng.Clone();
	this->_rsa_param = other._rsa_param;
}

RSATools::RSATools(const string &e, const string&n)
{
	Integer int_e(e.c_str());
	Integer int_n(n.c_str());

	_rsa_param.SetPublicExponent(int_e);
	_rsa_param.SetModulus(int_n);
}

string RSATools::encrypt(const string &plain)
{
	string cipher;
	RSA::PublicKey public_key(_rsa_param);
	RSAES_OAEP_SHA_Encryptor encryptor(public_key);
	StringSource(plain, true, new PK_EncryptorFilter(_rng, encryptor,
			new StringSink(cipher)));

	return cipher;
}

string RSATools::decrypt(const string &cipher)
{
	string recovered;
	RSA::PrivateKey private_key(_rsa_param);
	RSAES_OAEP_SHA_Decryptor decryptor(private_key);
	StringSource(cipher, true, new PK_DecryptorFilter(_rng, decryptor,
			new StringSink(recovered)));

	return recovered;
}

string RSATools::getPublicExponent()
{
	ostringstream os;
	os << _rsa_param.GetPublicExponent();

	string ret = os.str();
	ret.erase(ret.size() - 1);
	return ret;
}

string RSATools::getModulus()
{
	ostringstream os;
	os << _rsa_param.GetModulus();

	string ret = os.str();
	ret.erase(ret.length() - 1);
	return ret;
}

string RSATools::encryptWithBase64(const string &plain)
{
	//先加密
	string cipher = encrypt(plain);

	//然后转化为Base64
	std::istringstream in(cipher);
	std::ostringstream out;

	base64::encoder E;
	E.encode(in, out);

	return out.str();
}

string RSATools::decryptWithBase64(const string &cipher_b64)
{
	//先Base64解码
	std::istringstream in(cipher_b64);
	std::ostringstream out;
	base64::decoder D;
	D.decode(in, out);

	//然后解密
	string cipher = out.str();
	return decrypt(cipher);
}
